package org.yanghaokun.order.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yanghaokun.basic.service.impl.BaseServiceImpl;
import org.yanghaokun.basic.util.CodeGenerateUtils;
import org.yanghaokun.basic.util.PageList;
import org.yanghaokun.order.domain.AdoptOrder;
import org.yanghaokun.order.domain.OrderAddress;
import org.yanghaokun.order.mapper.AdoptOrderMapper;
import org.yanghaokun.order.mapper.OrderAddressMapper;
import org.yanghaokun.order.query.AdoptOrderQuery;
import org.yanghaokun.order.service.IAdoptOrderService;
import org.yanghaokun.org.domain.Employee;
import org.yanghaokun.org.mapper.EmployeeMapper;
import org.yanghaokun.pay.constants.PayConstants;
import org.yanghaokun.pay.domain.PayBill;
import org.yanghaokun.pay.mapper.PayBillMapper;
import org.yanghaokun.pay.service.IPayBillService;
import org.yanghaokun.pet.domain.Pet;
import org.yanghaokun.pet.mapper.PetMapper;
import org.yanghaokun.quartz.service.IQuartzService;
import org.yanghaokun.quartz.utils.JobConstants;
import org.yanghaokun.quartz.utils.QuartzJobInfo;
import org.yanghaokun.user.domain.LoginInfo;
import org.yanghaokun.user.domain.User;
import org.yanghaokun.user.domain.UserAddress;
import org.yanghaokun.user.mapper.UserAddressMapper;
import org.yanghaokun.user.mapper.UserMapper;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends BaseServiceImpl<AdoptOrder> implements IAdoptOrderService {

    @Autowired
    private PetMapper petMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private AdoptOrderMapper adoptOrderMapper;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private PayBillMapper payBillMapper;
    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private IQuartzService quartzService;
    @Override
    public String submit(Map<String, Object> params, LoginInfo loginInfo) {
        //前台传过来的四个参数，我们需要从对象中一一取出
        Long petId = Long.valueOf(params.get("pet_id").toString()); //宠物id
        Long addressId = Long.valueOf(params.get("address_id").toString());//用户地址id
        Integer serviceMethod = Integer.valueOf(params.get("service_method").toString()); //配送方式
        Integer payMethod = Integer.valueOf(params.get("pay_method").toString()); //支付方式
        //修改宠物状态为下架，下线时间也要一起修改
        Pet pet = petMapper.findOne(petId);
        pet.setState(0);
        pet.setOffsaletime(new Date());
        pet.setType_id(pet.getType().getId());
        //首先获取用户id，我们才能为后面的宠物绑定用户做准备
        User user = userMapper.findByloginId(loginInfo.getId());
        pet.setUser_id(user.getId());
        pet.setUser(user);
        petMapper.update(pet);
        //创建领养订单
        String unionPaySn = CodeGenerateUtils.generateUnionPaySn(); //先设置支付单号，后面直接获取
        AdoptOrder adoptOrder = initAdoptOrder(pet, addressId, user);
        adoptOrder.setPaySn(unionPaySn);
        adoptOrderMapper.save(adoptOrder);
        //配送方式的添加 @TODO
        //创建订单的地址
        //根据用户的地址来转化为订单地址
        UserAddress userAddress = userAddressMapper.findOne(addressId);
        OrderAddress orderAddress = userAddress2OrderAddress(userAddress, adoptOrder);
        //保存订单
        orderAddressMapper.save(orderAddress);
        //创建支付订单斌发起支付请求
        //创建支付订单
        PayBill payBill = buildBill(payMethod, pet,user, adoptOrder);
        payBillMapper.save(payBill);
        //对支付单发起支付请求-就是支付模块给我提供一个支付接口service方法
        String payData = payBillService.payRequest(payBill);
        //我们先创建一个需要将数据封装进去的类
        QuartzJobInfo info = new QuartzJobInfo();
        //我们需要设置进去订单的类型进去，因为我们是通过type来区分每个订单的job
        info.setType(JobConstants.JOB_TYPE_ADOPT_ORDER_CANCEL);
        //我们在后面的执行可知我么嗯需要当前订单的id传递参数进去
        Map<String, Object> adopetOrderparams = new HashMap<>();
        adopetOrderparams.put("orderId",adoptOrder.getId());
        info.setParams(adopetOrderparams);
        //设置触发时间
        info.setFireDate(adoptOrder.getLastPayTime());
        //设置名字，但是名字千万不能重复
        info.setJobName(JobConstants.ADOPT_ORDER_CANCEL_PREFIX + adoptOrder.getId());
        //添加定时任务
        quartzService.addJob(info);
        System.out.println(info.getJobName() + "被添加了！！！");
        return payData;
    }

    private PayBill buildBill(Integer payMethod, Pet pet, User user, AdoptOrder adoptOrder) {
        PayBill payBill = new PayBill();
        payBill.setDigest(adoptOrder.getDigest());
        payBill.setMoney(adoptOrder.getPrice());
        payBill.setState(0);
        payBill.setLastPayTime(new Date(System.currentTimeMillis()+ PayConstants.ORDER_TIMEOUT));
        payBill.setPayChannel(Long.valueOf(payMethod));
        payBill.setUnionPaySn(adoptOrder.getPaySn());
        payBill.setBusinessType(PayConstants.BUSINESS_TYPE_ADOPT);
        payBill.setBusinessKey(adoptOrder.getId());
        payBill.setUser_id(user.getId());
        payBill.setNickName(user.getUsername());
        payBill.setShopName(pet.getShop().getName());
        payBill.setShop_id(pet.getShop().getId());
        return payBill;
    }

    /**
     * 因为在设计的时候我们知道平台管理原可以查看全部的信息，所以我们不需要在这里考虑平台管理员的逻辑处理
     * 所以我们在这里只需要给查询条件传入一个shop_id就可以知道是店员
     * @param adoptOrderQuery
     * @param loginInfo
     * @return
     */
    @Override
    public PageList<AdoptOrder> queryAdminOrder(AdoptOrderQuery adoptOrderQuery, LoginInfo loginInfo) {
        Employee employee = employeeMapper.findByloginInfoId(loginInfo.getId());
        adoptOrderQuery.setShopId(employee.getShop_id());
        return super.getList(adoptOrderQuery);
    }

    @Override
    public PageList<AdoptOrder> queryUserOrder(AdoptOrderQuery adoptOrderQuery, LoginInfo loginInfo) {
        User user = userMapper.findByloginId(loginInfo.getId());
        adoptOrderQuery.setUserId(user.getId());
        return super.getList(adoptOrderQuery);
    }

    @Override
    public void cancleById(Long orderId) {
        //我们要查粗领养订单
        System.out.println("order" + orderId);
        AdoptOrder adoptOrder = adoptOrderMapper.findOne(orderId);
        //修改领养订单的状态
        adoptOrder.setState(-1);
        //更新一下
        adoptOrderMapper.update(adoptOrder);
        //支付订单也要一起修改状态
        String paySn = adoptOrder.getPaySn();
        System.out.println("pay" + paySn);
        PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        System.out.println("bill" + payBill);
        payBill.setState(-1);
        payBillMapper.update(payBill);

        System.out.println(adoptOrder.getDigest() + "订单已被quartz自动取消了");
    }

    private AdoptOrder initAdoptOrder(Pet pet, Long addressId, User user) {
        //创建一个订单
        AdoptOrder adoptOrder = new AdoptOrder();
        //初始化领养订单
        adoptOrder.setDigest("【摘要】领养" + pet.getName() + "的订单");
        adoptOrder.setState(0); //待支付
        adoptOrder.setPrice(pet.getSaleprice());
        adoptOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        adoptOrder.setLastPayTime(new Date(System.currentTimeMillis() +PayConstants.ORDER_TIMEOUT));
        adoptOrder.setPet_id(pet.getId());
        adoptOrder.setUser_id(user.getId());
        adoptOrder.setAddress_id(addressId);
        adoptOrder.setShop_id(pet.getShop().getId());
        return adoptOrder;
    }

    private OrderAddress userAddress2OrderAddress(UserAddress userAddress, AdoptOrder adoptOrder) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        orderAddress.setId(null);
        orderAddress.setOrder_id(adoptOrder.getId());
        orderAddress.setOrderSn(adoptOrder.getOrderSn());
        return orderAddress;
    }
}
